/*
 * BSM6.0
 *
 * Copyright 2012-2013 (C) SINODATA CO., LTD. All Rights Reserved.
 */
package com.sinodata.bsm.center.web.action.resource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.RelationHelper;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.cache.ResTypeDispConfCache;
import com.sinodata.bsm.center.cache.TreeNodeSequenceCache;
import com.sinodata.bsm.center.purview.FunctionConstants;
import com.sinodata.bsm.center.purview.UserFunctionValidate;
import com.sinodata.bsm.center.service.resource.ResService;
import com.sinodata.bsm.center.service.resource.ResTypeDispConfService;
import com.sinodata.bsm.center.service.resource.ResTypeService;
import com.sinodata.bsm.center.service.resource.TreeNodeSequenceService;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.vo.ResType;
import com.sinodata.bsm.common.vo.ResTypeDispConf;
import com.sinodata.bsm.common.vo.TreeNodeSequence;

/**
 * <p>
 * Description: 
 * </p>
 *
 * @author fanshengchao
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-7-7 上午10:14:01          fanshengchao        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
public class ResCustomAction extends BaseAction {

    @Autowired
    private ResService resService;
    @Autowired
    private ResTypeService resTypeService;
    @Autowired
    private ResTypeDispConfCache resTypeDispConfCache;
    @Autowired
    private ResTypeDispConfService resTypeDispConfService;
    @Autowired
    private TreeNodeSequenceService treeNodeSequenceService;
    @Autowired
    private TreeNodeSequenceCache treeNodeSequenceCache;

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#delete()
     */
    @Override
    public String delete() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#input()
     */
    @Override
    public String input() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#list()
     */
    @Override
    public String list() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#prepareModel()
     */
    @Override
    protected void prepareModel() throws Exception {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#save()
     */
    @Override
    public String save() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 资源自定页面
     * @return
     */
    public String frame() {
        Long resId = Long.parseLong(Struts2Utils.getParameter("id"));
        Struts2Utils.setRequestAttribute("resId", resId);
        Long pId = Long.parseLong(Struts2Utils.getParameter("pId"));
        Struts2Utils.setRequestAttribute("pId", pId);

        return "frame";
    }

    private List<List<ResBean>> children(Long parentResId) {
        List<ResBean> children = RelationHelper.children(parentResId);
        List<List<ResBean>> types = new ArrayList<List<ResBean>>();
        for (ResBean child : children) {
            List<ResBean> type = null;
            for (int j = 0; j < types.size(); j++) {
                if (types.get(j).get(0).res().getResTypeId().longValue() == child.res().getResTypeId().longValue()) {
                    type = types.get(j);
                    break;
                }
            }
            if (type == null) {
                type = new ArrayList<ResBean>();
                types.add(type);
            }
            type.add(child);
        }
        return types;
    }

    /**
     * 资源树定制页面
     * @return
     */
    public String tree() {
        Long resId = Long.parseLong(Struts2Utils.getParameter("resId"));
        String pId = Struts2Utils.getParameter("pId");
        String parentNodeId = "2|" + resId + "|" + pId;//Struts2Utils.getParameter("pId");

        //保存当前节点的子节点
        JSONArray res = new JSONArray();

        //当前资源下的资源类别
        List<List<ResBean>> list = children(resId);

        JSONArray showDispConfs = new JSONArray();

        for (int i = 0; i < list.size(); i++) {
            List<ResBean> beans = list.get(i);
            ResType type = beans.get(0).type().resType();

            //验证是否有更改过原有的资源类型名称 有则替换成更改过的
            ResTypeDispConf showDispConf = resTypeDispConfCache.find(resId, type.getId());

            /**
             * 获取当前节点的子节点 -- 定制的顺序
             *  通过节点定制来判断是否显示资源分类而最终显示的节点数
             */
            JSONObject entity = new JSONObject();
            String nodeId = null;
            if (showDispConf != null) { //当前节点有定制
                if (showDispConf.getIsDisp().intValue() == 0 && beans.size() >= 1) { //定制的节点不显示节点分类
                    for (ResBean bean : beans) {
                        nodeId = "2|" + bean.res().getId() + "|" + resId;
                        JSONObject entity2 = new JSONObject();
                        entity2.element("name", bean.res().getName());
                        entity2.element("id", nodeId);
                        res.add(entity2);
                    }
                } else if (showDispConf.getIsDisp().intValue() == 1 && beans.size() >= 1) {
                    entity.element("name", showDispConf.getDispName() == null ? type.getName() : showDispConf.getDispName());
                    nodeId = "3|" + beans.get(0).type().resType().getId() + "|" + resId;
                    entity.element("id", nodeId);
                    res.add(entity);
                }
            } else if (showDispConf == null) { //未定制节点
                if (beans.size() > 1) { //未定制的节点根据 同一个资源类别下是否有大于1个的资源,如果同一个类别资源大于1则默认表示显示资源类别，否则不显示
                    entity.element("name", beans.get(0).type().resType().getName());
                    nodeId = "3|" + beans.get(0).type().resType().getId() + "|" + resId;
                    entity.element("id", nodeId);
                    res.add(entity);
                } else {
                    for (ResBean bean : beans) {
                        nodeId = "2|" + bean.res().getId() + "|" + resId;
                        JSONObject entity2 = new JSONObject();
                        entity2.element("name", bean.res().getName());
                        entity2.element("id", nodeId);
                        res.add(entity2);
                    }
                }
            }

            JSONObject object = new JSONObject();
            if (showDispConf == null) {
                object.element("name", "");
                object.element("isDisp", beans.size() > 1 ? 1 : 0);
                object.element("resId", resId);
                object.element("resTypeId", type.getId());
            } else {
                object.element("name", showDispConf.getDispName() == null ? "" : showDispConf.getDispName());
                object.element("isDisp", showDispConf.getIsDisp());
                object.element("resId", showDispConf.getResId());
                object.element("resTypeId", showDispConf.getResTypeId());
            }

            object.element("typeName", type.getName());
            showDispConfs.add(object);
        }
        this.sortChildNodeSequence(parentNodeId, res);
        boolean hasPrivilege = UserFunctionValidate.resFunctionValidate(resId, FunctionConstants.EDIT_RES);
        Struts2Utils.setRequestAttribute("hasEditResPrivilege", hasPrivilege);
        Struts2Utils.setRequestAttribute("dispConfs", showDispConfs);
        Struts2Utils.setRequestAttribute("resId", resId);
        Struts2Utils.setRequestAttribute("res", res);
        return "tree";
    }

    /**
     * 保存定制的资源类别
     * @return
     */
    public String saveResTypeDispConf() {
        try {
            Long rId = Long.parseLong(Struts2Utils.getParameter("resId"));
            String arrayValue = Struts2Utils.getParameter("dispConfs");
            String[] dispConfArray = arrayValue.split("#");

            //封装数据
            List<ResTypeDispConf> dispConfs = new ArrayList<ResTypeDispConf>();
            for (String dispConfValues : dispConfArray) {
                String[] dispConfValue = dispConfValues.split(",");
                ResTypeDispConf dispConf = new ResTypeDispConf();
                Object resId = dispConfValue[0];
                Object resTypeId = dispConfValue[1];
                Object isDisp = dispConfValue[2];
                Object dispName = dispConfValue.length > 3 ? dispConfValue[3] : "";

                dispConf.setResId(Long.parseLong(resId.toString()));
                dispConf.setResTypeId(Long.parseLong(resTypeId.toString()));
                dispConf.setIsDisp(Integer.parseInt(isDisp.toString()));
                if (dispName != null && !dispName.toString().trim().equals("") && isDisp.toString().equals("1")) {
                    dispConf.setDispName(dispName.toString());
                }
                dispConfs.add(dispConf);
            }

            resTypeDispConfService.save(rId, dispConfs);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String saveTreeNodeSequence() {
        String parentNodeId = Struts2Utils.getParameter("nodeId");
        String childIdValues = Struts2Utils.getParameter("childIds");
        String name = Struts2Utils.getParameter("name");

        TreeNodeSequence nodeSequence = new TreeNodeSequence();
        nodeSequence.setChildNodeIds(childIdValues);
        nodeSequence.setParentNodeId(parentNodeId);
        treeNodeSequenceService.batchSaveOrUpdateTreeNodeSequence(nodeSequence);

        return null;
    }

    /**
     * 节点排序  页面显示前对资源进行排序，与树显示顺序一致
     * @param parentNodeId   节点ID(非资源ID)
     * @param children        节点数组
     */
    private void sortChildNodeSequence(String parentNodeId, JSONArray children) {
        if (treeNodeSequenceCache.hasNodeConf(parentNodeId)) {
            String[] array = treeNodeSequenceCache.get(parentNodeId).getChildNodeIds().split("[$]");
            TreeNodeCompare compare = new TreeNodeCompare(array);
            Collections.sort(children, compare);
        }
    }

    private class TreeNodeCompare implements Comparator {
        private final Map<String, Integer> nodeMap = new HashMap<String, Integer>();

        TreeNodeCompare(String[] nodeIds) {
            for (int i = 0; i < nodeIds.length; i++) {
                nodeMap.put(nodeIds[i], i);
            }
        }

        @Override
        public int compare(Object o1, Object o2) {
            String nodeId1 = ((JSONObject) o1).getString("id");
            String nodeId2 = ((JSONObject) o2).getString("id");
            int i1 = nodeMap.containsKey(nodeId1) ? nodeMap.get(nodeId1) : Integer.MAX_VALUE;
            int i2 = nodeMap.containsKey(nodeId2) ? nodeMap.get(nodeId2) : Integer.MAX_VALUE;
            return i1 - i2;
        }
    }

    /* (non-Javadoc)
     * @see com.opensymphony.xwork2.ModelDriven#getModel()
     */
    @Override
    public Object getModel() {
        // TODO Auto-generated method stub
        return null;
    }
}
